package com.unlcn.ils.wms.backend.service.sys.impl;

import cn.huiyunche.commons.domain.PageVo;
import cn.huiyunche.commons.exception.BusinessException;
import com.google.common.collect.Maps;
import com.unlcn.ils.wms.backend.bo.baseDataBO.WmsWarehouseBO;
import com.unlcn.ils.wms.backend.bo.sys.SysUserBO;
import com.unlcn.ils.wms.backend.dto.sysDTO.RoleDTO;
import com.unlcn.ils.wms.backend.dto.sysDTO.UserDTO;
import com.unlcn.ils.wms.backend.enums.*;
import com.unlcn.ils.wms.backend.service.baseData.WmsWarehouseService;
import com.unlcn.ils.wms.backend.service.sys.PermissionsService;
import com.unlcn.ils.wms.backend.service.sys.SysRoleService;
import com.unlcn.ils.wms.backend.service.sys.SysUserService;
import com.unlcn.ils.wms.base.dto.SysUserDTO;
import com.unlcn.ils.wms.base.mapper.extmapper.SysUserCustomMapper;
import com.unlcn.ils.wms.base.mapper.sys.SysRoleMapper;
import com.unlcn.ils.wms.base.mapper.sys.SysUserMapper;
import com.unlcn.ils.wms.base.mapper.sys.SysUserRoleMapper;
import com.unlcn.ils.wms.base.model.stock.WmsWarehouse;
import com.unlcn.ils.wms.base.model.sys.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.regex.Pattern;

/**
 * @Auther linbao
 * @Date 2017-10-12
 */
@Service
public class SysUserServiceImpl implements SysUserService {

    private Logger LOGGER = LoggerFactory.getLogger(SysUserServiceImpl.class);

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysUserCustomMapper sysUserCustomMapper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private WmsWarehouseService wmsWarehouseService;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private PermissionsService permissionsService;


    @Value("${md5.salt}")
    private String salt;

    /**
     * pc登录
     *
     * @param sysUserBO
     * @throws Exception
     */
    @Override
    public SysUserDTO loginForWeb(SysUserBO sysUserBO) throws Exception {
        LOGGER.info("SysUserServiceImpl.loginForWeb param: {}", sysUserBO);
        SysUserDTO sysUserDTO = new SysUserDTO();
        checkParam(sysUserBO);
        if (StringUtils.isBlank(sysUserBO.getUsername())) {
            throw new BusinessException("请输入账户");
        }
        if (StringUtils.isBlank(sysUserBO.getPassword())) {
            throw new BusinessException("请输入密码");
        }
        SysUserExample userExample = new SysUserExample();
        SysUserExample.Criteria criteria = userExample.createCriteria();
        criteria.andUsernameEqualTo(sysUserBO.getUsername());
        //criteria.andPasswordEqualTo(sysUserBO.getPassword());
        Md5PasswordEncoder md5PasswordEncoder = new Md5PasswordEncoder();
        criteria.andPasswordEqualTo(md5PasswordEncoder.encodePassword(sysUserBO.getPassword(), salt));
        criteria.andTypeEqualTo(UserTypeEnum.NORMAL.getValue());
        criteria.andIsDeletedEqualTo(DeleteFlagEnum.NORMAL.getValue());
        criteria.andEnableEqualTo(StatusEnum.RIGHT.getValue());

        List<SysUser> sysUserList = sysUserMapper.selectByExample(userExample);
        if (CollectionUtils.isEmpty(sysUserList)
                && sysUserList.size() != 1) {
            throw new BusinessException("账户或者密码不正确");
        }

        SysUser sysUser = sysUserList.get(0);
        BeanUtils.copyProperties(sysUser, sysUserDTO);

        //对应的仓库id
        setWarehouseInfo(sysUserDTO);

        //获取权限
        List<SysRole> sysRoleList = sysRoleService.getRoleListByUserId(sysUser.getId());
        if (CollectionUtils.isNotEmpty(sysRoleList)) {
            List<Integer> roleIdList = new ArrayList<>();
            sysRoleList.stream()
                    .filter(sysRole -> !Objects.equals(sysRole, null))
                    .filter(sysRole -> !Objects.equals(sysRole.getId(), null))
                    .forEach(sysRole -> roleIdList.add(sysRole.getId()));

            if (CollectionUtils.isNotEmpty(roleIdList)) {
                sysUserDTO.setPermisssList(permissionsService.getPermissListByRoleIdList(roleIdList));
            }
        }
        return sysUserDTO;
    }

    /**
     * 设置所属仓库信息
     *
     * @param sysUserDTO
     */
    private void setWarehouseInfo(SysUserDTO sysUserDTO) {
        SysUserRoleExample userRoleExample = new SysUserRoleExample();
        userRoleExample.createCriteria().andUserIdEqualTo(sysUserDTO.getId());
        List<SysUserRole> userRoleList = sysUserRoleMapper.selectByExample(userRoleExample);
        if (CollectionUtils.isNotEmpty(userRoleList)) {
            sysUserDTO.setWarehouseId(userRoleList.get(0).getWarehouseId());
            WmsWarehouseBO wmsWarehouseBO = new WmsWarehouseBO();
            wmsWarehouseBO.setWhId(userRoleList.get(0).getWarehouseId());
            WmsWarehouse warehouse = wmsWarehouseService.findWarehouseById(wmsWarehouseBO);
            if (!Objects.equals(warehouse, null)) {
                sysUserDTO.setWhCode(warehouse.getWhCode());
                sysUserDTO.setWhName(warehouse.getWhName());
            }
        }
    }

    /**
     * 分页列表查询
     *
     * @param sysUserBO
     * @return
     * @throws Exception
     */
    @Override
    public Map<String, Object> listUser(SysUserBO sysUserBO) throws Exception {
        LOGGER.info("SysUserServiceImpl.listUser sysUserBO: {}", sysUserBO);
        checkParam(sysUserBO);

        Map<String, Object> resultMap = new HashMap<>();
        Map<String, Object> paramMap = new HashMap<>();


        if (StringUtils.isNotBlank(sysUserBO.getUsername())) {
            paramMap.put("username", sysUserBO.getUsername());
        }
        if (StringUtils.isNotBlank(sysUserBO.getName())) {
            paramMap.put("name", sysUserBO.getName());
        }
        if (StringUtils.isNotBlank(sysUserBO.getEnable())) {
            paramMap.put("enable", sysUserBO.getEnable());
        }
        //非删除状态
        paramMap.put("isDeleted", DeleteFlagEnum.NORMAL.getValue());
        paramMap.put("limitStart", sysUserBO.getStartIndex());
        paramMap.put("limitEnd", sysUserBO.getPageSize());
        PageVo pageVo = new PageVo();
        pageVo.setTotalRecord(sysUserCustomMapper.countUserList(paramMap));
        pageVo.setPageNo(sysUserBO.getPageNo());
        pageVo.setPageSize(sysUserBO.getPageSize());

        resultMap.put("page", pageVo);
        resultMap.put("dataList", sysUserCustomMapper.selectUserList(paramMap));
        return resultMap;
    }

    /**
     * 新增
     *
     * @param sysUserBO
     * @throws Exception
     */
    @Override
    public void addSysUser(SysUserBO sysUserBO) throws Exception {
        LOGGER.info("SysUserServiceImpl.addSysUser sysUserBO: {}", sysUserBO);
        checkParam(sysUserBO);
        compareParam(sysUserBO, false);

        //仓库和角色的校验
        checkRole(sysUserBO.getRoleIdList());
        checkWarehouse(sysUserBO.getWarehouseId());

        ///校验用户名唯一性
        boolean uniqueneResult = checkUserNameUniquene(sysUserBO);
        if (!uniqueneResult) {
            throw new BusinessException("用户名不唯一");
        }

        //TODO 保存用户
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(sysUserBO, sysUser);
        sysUser.setId(null);
        sysUser.setGmtCreate(new Date());
        sysUser.setGmtModified(new Date());
        sysUser.setCreatePerson(sysUserBO.getCurrenUser());
        sysUser.setUpdatePerson(sysUserBO.getCurrenUser());
        sysUser.setIsDeleted(DeleteFlagEnum.NORMAL.getValue());
        Md5PasswordEncoder md5PasswordEncoder = new Md5PasswordEncoder();
        sysUser.setPassword(md5PasswordEncoder.encodePassword(sysUser.getPassword(), salt));
        sysUserMapper.insertSelective(sysUser);

        //TODO 保存用户, 角色关系
        saveUserRole(sysUser.getId(), sysUserBO.getWarehouseId(), sysUserBO.getRoleIdList());
    }

    /**
     * 修改
     *
     * @param sysUserBO
     * @throws Exception
     */
    @Override
    public void updateSysUser(SysUserBO sysUserBO) throws Exception {
        LOGGER.info("SysUserServiceImpl.addSysUser sysUserBO: {}", sysUserBO);
        checkParam(sysUserBO);
        compareParam(sysUserBO, true);
        //校验用户是否存在
        findSelectUser(sysUserBO.getId());
        //仓库和角色的校验
        checkRole(sysUserBO.getRoleIdList());
        checkWarehouse(sysUserBO.getWarehouseId());

        //校验用户名唯一性
        boolean uniqueneResult = checkUserNameUniquene(sysUserBO);
        if (!uniqueneResult) {
            throw new BusinessException("用户名不唯一");
        }


        //TODO 保存用户
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(sysUserBO, sysUser);
        sysUser.setGmtModified(new Date());
        sysUser.setUpdatePerson(sysUserBO.getCurrenUser());
        if (StringUtils.isNotBlank(sysUser.getPassword())) {
            Md5PasswordEncoder md5PasswordEncoder = new Md5PasswordEncoder();
            sysUser.setPassword(md5PasswordEncoder.encodePassword(sysUser.getPassword(), salt));
        }
        sysUserMapper.updateByPrimaryKeySelective(sysUser);

        //TODO 删除用户角色关系
        deleteUserRoleByUserId(sysUserBO.getId());

        //TODO 保存用户, 角色关系
        saveUserRole(sysUser.getId(), sysUserBO.getWarehouseId(), sysUserBO.getRoleIdList());
    }

    /**
     * 删除
     *
     * @param sysUserBO
     * @throws Exception
     */
    @Override
    public void deleteSysUser(SysUserBO sysUserBO) throws Exception {
        LOGGER.info("SysUserServiceImpl.addSysUser sysUserBO: {}", sysUserBO);
        checkParam(sysUserBO);
        //findSelectUser(sysUserBO.getId());
        //删除对应的用户 - 物理删除
        //sysUserMapper.deleteByPrimaryKey(sysUserBO.getId());
        //删除对应的用户 - 逻辑删除
        //SysUser sysUser = new SysUser();
        //sysUser.setId(sysUserBO.getId());
        //sysUser.setIsDeleted(DeleteFlagEnum.NOT_QUIT.getValue());
        //sysUserMapper.updateByPrimaryKeySelective(sysUser);
        //
        ////删除用户角色关系
        //deleteUserRoleByUserId(sysUserBO.getId());

        if (CollectionUtils.isEmpty(sysUserBO.getUserIdList())) {
            throw new BusinessException("请选择要删除用户");
        }
        SysUser sysUser = new SysUser();
        sysUser.setIsDeleted(DeleteFlagEnum.DELETED.getValue());

        SysUserExample userExample = new SysUserExample();
        userExample.createCriteria().andIdIn(sysUserBO.getUserIdList());
        sysUserMapper.updateByExampleSelective(sysUser, userExample);

        //删除用户角色关系
        SysUserRoleExample userRoleExample = new SysUserRoleExample();
        userRoleExample.createCriteria().andUserIdIn(sysUserBO.getUserIdList());
        sysUserRoleMapper.deleteByExample(userRoleExample);
    }

    /**
     * 判断用户名是否唯一
     *
     * @param sysUserBO
     * @return false - 不唯一, true-唯一
     * @throws Exception
     */
    @Override
    public boolean checkUserNameUniquene(SysUserBO sysUserBO) throws Exception {
        LOGGER.info("SysUserServiceImpl.checkUserNameUniquene sysUserBO: {}", sysUserBO);
        //TODO 校验
        checkParam(sysUserBO);

        boolean resultBoolean = false;
        SysUserExample userExample = new SysUserExample();
        SysUserExample.Criteria criteria = userExample.createCriteria();
        criteria.andUsernameEqualTo(sysUserBO.getUsername());
        criteria.andIsDeletedEqualTo(DeleteFlagEnum.NORMAL.getValue());
        //id不为空
        if (!Objects.equals(sysUserBO.getId(), null)) {
            criteria.andIdNotEqualTo(sysUserBO.getId());
        }
        int resultCount = sysUserMapper.countByExample(userExample);
        if (resultCount <= 0) {
            resultBoolean = true;
        }
        return resultBoolean;
    }

    /**
     * 获取用户
     *
     * @param sysUserBO
     * @return
     * @throws Exception
     */
    @Override
    public UserDTO findSysUserById(SysUserBO sysUserBO) throws Exception {

        UserDTO userDTO = new UserDTO();
        SysUser selectUser = sysUserMapper.selectByPrimaryKey(sysUserBO.getId());
        if (Objects.equals(selectUser, null)) {
            throw new BusinessException("找不到对应的用户数据");
        }
        BeanUtils.copyProperties(selectUser, userDTO);
        userDTO.setPassword(null);

        //获取对应的仓库id
        SysUserRoleExample userRoleExample = new SysUserRoleExample();
        userRoleExample.createCriteria().andUserIdEqualTo(sysUserBO.getId());
        List<SysUserRole> userRoleList = sysUserRoleMapper.selectByExample(userRoleExample);
        if (CollectionUtils.isNotEmpty(userRoleList)) {
            userDTO.setWarehouseId(userRoleList.get(0).getWarehouseId());
        }

        //获取角色列表
        List<SysRole> sysRoleList = sysRoleService.getRoleListByUserId(sysUserBO.getId());
        if (CollectionUtils.isNotEmpty(sysRoleList)) {
            List<RoleDTO> roleDTOList = new ArrayList<>();
            RoleDTO roleDTO = null;
            for (SysRole sysRole : sysRoleList) {
                if (!Objects.equals(sysRole, null)) {
                    roleDTO = new RoleDTO();
                    BeanUtils.copyProperties(sysRole, roleDTO);
                    roleDTOList.add(roleDTO);
                    roleDTO = null;
                }
            }
            userDTO.setRoleList(roleDTOList);
        }

        return userDTO;
    }

    /**
     * 根据userId获取用户
     *
     * @param userId
     */
    @Override
    public SysUser selectUserById(String userId) throws Exception {
        SysUser sysUser = null;
        if (StringUtils.isNotBlank(userId)) {
            sysUser = sysUserMapper.selectByPrimaryKey(Integer.parseInt(userId));
        }
        return sysUser;
    }

    @Override
    public List<SysUser> getUserByWarehouseOld(SysUserBO sysUserBO) {
        if (sysUserBO.getType() == null)
            throw new BusinessException("用户类型不能为空");
        if (sysUserBO.getWarehouseCode() == null)
            throw new BusinessException("仓库code不能为空");
        return sysUserCustomMapper.getUserByWarehouse(Integer.valueOf(sysUserBO.getType()), sysUserBO.getWarehouseCode());
    }

    @Override
    public List<SysUser> getUserByWarehouse(SysUserBO sysUserBO) {
        if (sysUserBO.getType() == null)
            throw new BusinessException("用户类型不能为空");
        if (sysUserBO.getWarehouseCode() == null)
            throw new BusinessException("仓库code不能为空");
        //return sysUserCustomMapper.getUserByWarehouse(Integer.valueOf(sysUserBO.getType()), sysUserBO.getWarehouseCode());
        HashMap<String, Object> params = Maps.newHashMap();
        params.put("whCode", sysUserBO.getWarehouseCode());
        params.put("notDel", DeleteFlagEnum.NORMAL.getValue());
        params.put("cancelStatus",WmsOutboundTaskStatusEnum.WMS_OUTBOUND_TASK_CANCLE.getValue());
        params.put("notQuit",TaskQuitFlagEnum.NOT_QUIT.getValue());
        return sysUserCustomMapper.selectOtDriverByWhCode(params);
    }

    /**
     * 保存用户角色关系表
     *
     * @param userId
     * @param warehouseId
     * @param roleIdList
     */
    private void saveUserRole(Integer userId, Long warehouseId, List<Integer> roleIdList) {
        if (CollectionUtils.isNotEmpty(roleIdList)) {
            for (Integer roleId : roleIdList) {
                if (!Objects.equals(roleId, null)) {
                    SysUserRole sysUserRole = new SysUserRole();
                    sysUserRole.setUserId(userId);
                    sysUserRole.setWarehouseId(warehouseId);
                    sysUserRole.setRoleId(roleId);
                    sysUserRoleMapper.insertSelective(sysUserRole);
                }
            }
        }
    }

    /**
     * 根据用户id删除对应的用户角色关系
     *
     * @param userId
     */
    private void deleteUserRoleByUserId(Integer userId) {
        SysUserRoleExample userRoleExample = new SysUserRoleExample();
        userRoleExample.createCriteria().andUserIdEqualTo(userId);
        sysUserRoleMapper.deleteByExample(userRoleExample);
    }

    /**
     * 找对应用户
     *
     * @param userId
     */
    private void findSelectUser(Integer userId) {
        if (Objects.equals(userId, null)) {
            throw new BusinessException("请选择账户");
        }
        SysUser selectUser = sysUserMapper.selectByPrimaryKey(userId);
        if (Objects.equals(selectUser, null)) {
            throw new BusinessException("找不到对应的用户");
        }
    }

    /**
     * 校验仓库是否存在
     *
     * @param warehouseId
     */
    private void checkWarehouse(Long warehouseId) throws Exception {
        if (Objects.equals(warehouseId, null)) {
            throw new BusinessException("");
        }
        WmsWarehouseBO wmsWarehouseBO = new WmsWarehouseBO();
        wmsWarehouseBO.setWhId(warehouseId);
        WmsWarehouse warehouse = wmsWarehouseService.findWarehouseById(wmsWarehouseBO);
        if (Objects.equals(warehouse, null)) {
            throw new BusinessException("找不到对应的所属仓库信息");
        }
    }

    /**
     * 校验角色是否存在
     *
     * @param roleIdList
     */
    private void checkRole(List<Integer> roleIdList) {
        if (CollectionUtils.isEmpty(roleIdList)) {
            throw new BusinessException("请选择角色");
        }
        SysRoleExample roleExample = new SysRoleExample();
        roleExample.createCriteria().andIdIn(roleIdList);
        List<SysRole> sysRoleList = sysRoleMapper.selectByExample(roleExample);
        if (CollectionUtils.isEmpty(sysRoleList)) {
            throw new BusinessException("找不到对应的角色信息");
        }

    }


    /**
     * 参数校验
     *
     * @param sysUserBO
     */
    private void checkParam(SysUserBO sysUserBO) {
        if (Objects.equals(sysUserBO, null)) {
            throw new BusinessException("参数为空");
        }
    }

    /**
     * 参数的规则校验
     *
     * @param sysUserBO
     */
    private void compareParam(SysUserBO sysUserBO, boolean isUpdate) {
        Pattern pattern = null;
        //账户
        if (StringUtils.isBlank(sysUserBO.getUsername())) {
            throw new BusinessException("账户不能为空");
        }
        //校验账号规则
        pattern = Pattern.compile("^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,32}$");
        if (!pattern.matcher(sysUserBO.getUsername()).matches()) {
            throw new BusinessException("账户必须是6到32字母和数字的组合");
        }
        //密码
        if (isUpdate) {
            //编辑
            if (StringUtils.isNotBlank(sysUserBO.getPassword())) {
                //校验密码规则
                pattern = Pattern.compile("^[0-9A-Za-z]{6,32}$");
                if (!pattern.matcher(sysUserBO.getPassword()).matches()) {
                    throw new BusinessException("密码必须是6到32字母或数字的组合");
                }
            }
        } else {
            //新增
            if (StringUtils.isBlank(sysUserBO.getPassword())) {
                throw new BusinessException("密码不能为空");
            }
            //校验密码规则
            pattern = Pattern.compile("^[0-9A-Za-z]{6,32}$");
            if (!pattern.matcher(sysUserBO.getPassword()).matches()) {
                throw new BusinessException("密码必须是6到32字母或数字的组合");
            }
        }
        //姓名
        if (StringUtils.isBlank(sysUserBO.getName())) {
            throw new BusinessException("姓名不能为空");
        }
        //仓库
        if (Objects.equals(sysUserBO.getWarehouseId(), null)) {
            throw new BusinessException("所属仓库不能为空");
        }
        //校验邮箱规则
        //if (StringUtils.isNotBlank(sysUserBO.getEmail())){
        //    pattern = Pattern.compile("^(\\w-*\\.*)+@(\\w-?)+(\\.\\w{2,})+$");
        //    if (!pattern.matcher(sysUserBO.getEmail()).matches()){
        //        throw new BusinessException("不是正确的邮箱格式");
        //    }
        //}
        //角色
        if (CollectionUtils.isEmpty(sysUserBO.getRoleIdList())) {
            throw new BusinessException("角色不能为空");
        }
    }
}
